package middleware

import (
	"github.com/gofiber/fiber/v2"
	"sg-backend/app/repository/userRepository"
	businessError "sg-backend/error"
	"sg-backend/global"
	"sg-backend/model/user"
	"sg-backend/utils"
	"strings"
	"time"
)

// AuthMiddleware jwt 校验中间件
func AuthMiddleware() fiber.Handler {
	return func(ctx *fiber.Ctx) error {
		// 获取token
		authorization := string(ctx.Request().Header.Peek(fiber.HeaderAuthorization))
		authArr := strings.Split(authorization, " ")
		if len(authArr) != 2 || authArr[0] != "Bearer" {
			panic(businessError.New(businessError.TOKEN_NOT_EXISTS))
		}
		tokenString := authArr[1]

		// 解析token
		customClaims, err := utils.ParseToken(tokenString)
		if err != nil {
			panic(businessError.New(businessError.TOKEN_PARSE_ERROR))
		}

		// 检测token是否过期
		// 主要是人为退出登录后的作废，并非token超过指定过期时间的过期
		tokenObj := user.Token{}
		r := global.DB.Where("token = ?", tokenString).First(&tokenObj)
		if r.Error != nil {
			return ctx.JSON(fiber.Map{
				"status":  "error",
				"success": false,
				"code":    30003,
				"message": "Token获取验证失败，请联系管理员！",
			})
		}

		// 判断是否过期
		if tokenObj.ExpireTime.Before(time.Now()) {

			// 过期时间早于当前时间，已过期
			panic(businessError.New(businessError.TOKEN_EXPIRED))
		}

		// 获取用户的信息
		userObj := userRepository.GetUserById(customClaims.UserId)
		if userObj == nil {
			panic(businessError.New(businessError.USER_NOT_FOUND))
		}

		// 将用户放入上下文中，方便提取
		global.SetAuthUser(userObj)

		return ctx.Next()
	}
}
